package com.myproxyDynamicSimulation;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import org.apache.commons.io.FileUtils;

public class Proxy {
	
	public static Object newProxyInstance(Class interf, InvocationHandler handler) throws Exception{
		String rt = "\r\n";
		
		String methodStr = "";
		for(Method m : interf.getMethods()){
			methodStr +=  "@Override"+ rt
			+ "public void "+m.getName()+"() {"+ rt
			+ "try{"+ rt
			+ "Method md = "+interf.getName()+".class.getMethod(\""+m.getName()+"\");"+rt
			+ "handler.invoke(this, md, null);"+ rt
			+ "}catch(Throwable e){e.printStackTrace();}"+ rt
			+ "}";
		}
		
		String str2 = "package com.myproxyDynamicSimulation;"+ rt
				+ "import java.lang.reflect.InvocationHandler;"+ rt
				+ "import java.lang.reflect.Method;" + rt
				+ "public class $Proxy0 implements "+interf.getName()+" {"+ rt
				+ "private InvocationHandler handler;"+ rt
				+ "public $Proxy0(InvocationHandler handler){"+ rt
				+ "this.handler = handler;}"+ rt
				+  methodStr+ rt
				+ "}";
		
		// 1.声明一段源码（动态产生代理）；.java
		//D:\workspace1\T1
		String filename = System.getProperty("user.dir") + "/build/classes/com/myproxyDynamicSimulation/$Proxy0.java";
		File file = new File(filename);
		FileUtils.writeStringToFile(file, str2);
		
		
		// 2.编译源码（JDK Compiler API）,产生一个代理类； .class
		//编译，
		//拿到编译器
		JavaCompiler compile = ToolProvider.getSystemJavaCompiler();
		//文件管理者
		StandardJavaFileManager fileManager = compile.getStandardFileManager(null, null, null);
		//获取文件
		Iterable compilationUnits = fileManager.getJavaFileObjects(filename);
		//编译任务
		CompilationTask task = compile.getTask(null, fileManager, null, null, null, compilationUnits);
		//进行编译
		task.call();
		fileManager.close();
		
		// 3.将这个类load到内存中，产生一个新的代理对象；
		ClassLoader loader = ClassLoader.getSystemClassLoader();
		Class c = loader.loadClass("com.myproxyDynamicSimulation.$Proxy0");
		Constructor ctr = c.getConstructor(InvocationHandler.class);
		return ctr.newInstance(handler);
	}
}
